package com.xinruke.hostels.manage.user.service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.xinruke.hostels.cache.extract.extractor.DictInfoCacheExtractor;
import com.xinruke.hostels.cache.extract.extractor.HotelInfoCacheExtractor;
import com.xinruke.hostels.common.cache.ManageUserCache;
import com.xinruke.hostels.common.cache.vo.LoginManageResultVO;
import com.xinruke.hostels.common.constants.SysDicConstant;
import com.xinruke.hostels.common.mybatis.MyExample;
import com.xinruke.hostels.common.po.XtYewuyonghu;
import com.xinruke.hostels.common.po.XtYonghujueseGuanxi;
import com.xinruke.hostels.common.util.CustomSecurity;
import com.xinruke.hostels.common.util.UUIDUtil;
import com.xinruke.hostels.common.vo.ErrorEnum;
import com.xinruke.hostels.common.vo.ResultVO;
import com.xinruke.hostels.common.vo.query.EConditionOperator;
import com.xinruke.hostels.common.vo.query.QueryConditions;
import com.xinruke.hostels.common.vo.query.RowsDataVO;
import com.xinruke.hostels.manage.user.interfaces.dto.*;
import com.xinruke.hostels.manage.user.mapper.XtYewuyonghuMapper;
import com.xinruke.hostels.manage.user.mapper.XtYonghujueseGuanxiMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.util.Sqls;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author GuoZheng
 * @ClassName UserServiceImpl
 * @date：2019/6/14
 * @version: V1.0.0
 * @description：
 */
@Service
public class UserService {
    @Resource
    private XtYewuyonghuMapper xtYewuyonghuMapper;

    @Resource
    private XtYonghujueseGuanxiMapper xtYonghujueseGuanxiMapper;

    @Autowired
    LoginService loginService;

    @Resource
    private ManageUserCache manageUserCache;

    @Resource
    private DictInfoCacheExtractor dictInfoCacheExtractor;
    @Resource
    private HotelInfoCacheExtractor hotelInfoCacheExtractor;

    @Transactional
    public ResultVO addDefaultUserInfo(UserInfoAddDefaultDTO userInfoAddDTO) {
        ResultVO resultVO = ResultVO.fail();

        List<XtYewuyonghu> xtYewuyonghuList = xtYewuyonghuMapper.selectByExample(Example.builder(XtYewuyonghu.class)
                .where(Sqls.custom()
                        .andEqualTo("yonghuming", userInfoAddDTO.getYonghuming())
                        .andEqualTo("shanchubiaoshi", XtYewuyonghu.SHANCHUBIAOSHI_WU_XIOA)
                ).build()
        );

        if (!CollectionUtils.isEmpty(xtYewuyonghuList)) {
            resultVO.setMessage("用户名已被占用");
            return resultVO;
        }

        XtYewuyonghu user = new XtYewuyonghu();
        BeanUtils.copyProperties(userInfoAddDTO, user);

        user.setChuangjianrenId(userInfoAddDTO.getCurrentUserId());
        user.setYan(UUIDUtil.getUUID());
        user.setChuangjianshijian(new Date());
        user.setZhuangtai(XtYewuyonghu.ZHUANGTAI_YOU_XIAO);
        user.setSuoshuxitong(userInfoAddDTO.getSuoshuxitong());
        user.setShanchubiaoshi(XtYewuyonghu.SHANCHUBIAOSHI_WU_XIOA);
        user.setGengxinshijian(new Date());
        user.setGengxinrenId(userInfoAddDTO.getCurrentUserId());
        //针对huiyuan中的密码、手机号、身份证号，做加密处理
        String password = user.getMima();
        password = CustomSecurity.createUserPassword(user.getYonghuming(), user.getYan(), password);
        user.setMima(password);
        xtYewuyonghuMapper.insert(user);
        //配置角色
        if (!CollectionUtils.isEmpty(userInfoAddDTO.getRoleIds())) {
            List<XtYonghujueseGuanxi> userRoles = userInfoAddDTO.getRoleIds().stream().map(r ->
                    new XtYonghujueseGuanxi(null, user.getId(), r, XtYonghujueseGuanxi.SHANCHUBIAOSHI_WU_XIOA)).collect(Collectors.toList());
            xtYonghujueseGuanxiMapper.insertList(userRoles);
        }
        resultVO.setCode(ResultVO.SUCCESS);
        resultVO.setMessage("操作成功");
        return resultVO;
    }

    @Transactional
    public ResultVO addUserInfo(UserInfoAddDTO userInfoAddDTO) {
        ResultVO resultVO = ResultVO.fail();

        List<XtYewuyonghu> xtYewuyonghuList = xtYewuyonghuMapper.selectByExample(Example.builder(XtYewuyonghu.class)
                .where(Sqls.custom()
                        .andEqualTo("yonghuming", userInfoAddDTO.getYonghuming())
                        .andEqualTo("shanchubiaoshi", XtYewuyonghu.SHANCHUBIAOSHI_WU_XIOA)
                ).build()
        );

        if (!CollectionUtils.isEmpty(xtYewuyonghuList)) {
            resultVO.setMessage("用户名已被占用");
            return resultVO;
        }

        XtYewuyonghu user = new XtYewuyonghu();
        BeanUtils.copyProperties(userInfoAddDTO, user);

        user.setChuangjianrenId(manageUserCache.getCurrentUserId());
        user.setYan(UUIDUtil.getUUID());
        user.setChuangjianshijian(new Date());
        user.setZhuangtai(XtYewuyonghu.ZHUANGTAI_YOU_XIAO);
        user.setSuoshuxitong(userInfoAddDTO.getSuoshuxitong());
        user.setShanchubiaoshi(XtYewuyonghu.SHANCHUBIAOSHI_WU_XIOA);
        user.setGengxinshijian(new Date());
        user.setGengxinrenId(manageUserCache.getCurrentUserId());
        //针对huiyuan中的密码、手机号、身份证号，做加密处理
        String password = user.getMima();
        password = CustomSecurity.createUserPassword(user.getYonghuming(), user.getYan(), password);
        user.setMima(password);
        xtYewuyonghuMapper.insert(user);
        //配置角色
        if (!CollectionUtils.isEmpty(userInfoAddDTO.getRoleIds())) {
            List<XtYonghujueseGuanxi> userRoles = userInfoAddDTO.getRoleIds().stream().map(r ->
                    new XtYonghujueseGuanxi(null, user.getId(), r, XtYonghujueseGuanxi.SHANCHUBIAOSHI_WU_XIOA)).collect(Collectors.toList());
            xtYonghujueseGuanxiMapper.insertList(userRoles);
        }
        resultVO.setCode(ResultVO.SUCCESS);
        resultVO.setMessage("操作成功");
        return resultVO;

    }

    @Transactional
    public ResultVO modifyUserInfo(UserInfoModifyDTO userInfoModifyDTO) {
        ResultVO resultVO = ResultVO.fail();
        XtYewuyonghu user = new XtYewuyonghu();
        BeanUtils.copyProperties(userInfoModifyDTO, user);
        XtYewuyonghu yewuyonghu = xtYewuyonghuMapper.selectByPrimaryKey(userInfoModifyDTO.getId());
        if (yewuyonghu == null) {
            resultVO.setMessage("用户不存在");
            return resultVO;
        }
        if (StringUtils.isEmpty(userInfoModifyDTO.getYonghuming())) {
            user.setYonghuming(yewuyonghu.getYonghuming());
        }
        String uuid = UUIDUtil.getUUID();
        if (!StringUtils.isEmpty(user.getMima())) {
            user.setYan(uuid);
            String password = CustomSecurity.createUserPassword(user.getYonghuming(), user.getYan(), user.getMima());
            user.setMima(password);
        } else {
            user.setMima(null);
        }
        user.setGengxinrenId(manageUserCache.getCurrentUserId());
        user.setZhuangtai(XtYewuyonghu.ZHUANGTAI_YOU_XIAO);
        user.setShanchubiaoshi(XtYewuyonghu.SHANCHUBIAOSHI_WU_XIOA);
        user.setGengxinshijian(new Date());
        if (!CollectionUtils.isEmpty(userInfoModifyDTO.getRoleIds())) {
            List<XtYonghujueseGuanxi> userRoles = userInfoModifyDTO.getRoleIds().stream().map(r -> new XtYonghujueseGuanxi(null, userInfoModifyDTO.getId(), r, XtYonghujueseGuanxi.SHANCHUBIAOSHI_WU_XIOA)).collect(Collectors.toList());

            xtYonghujueseGuanxiMapper.delUserRoleByUserId(userInfoModifyDTO.getId());
            xtYonghujueseGuanxiMapper.insertList(userRoles);
        }
        xtYewuyonghuMapper.updateByPrimaryKeySelective(user);
        resultVO.setCode(ResultVO.SUCCESS);
        resultVO.setMessage("操作成功");
        return resultVO;

    }

    @Transactional
    public int deleteUserInfo(UserInfoDelDto userInfoDelDto) {

        XtYewuyonghu user = new XtYewuyonghu();
        user.setId(userInfoDelDto.getId());
        user.setGengxinrenId(manageUserCache.getCurrentUserId());
        user.setZhuangtai(XtYewuyonghu.ZHUANGTAI_WU_XIOA);
        user.setShanchubiaoshi(XtYewuyonghu.SHANCHUBIAOSHI_YOU_XIAO);
        user.setGengxinshijian(new Date());
        xtYonghujueseGuanxiMapper.delUserRoleByUserId(userInfoDelDto.getId());
        return xtYewuyonghuMapper.updateByPrimaryKeySelective(user);
    }

    public RowsDataVO<UserInfoQueryResultDTO> getUserInfoList(UserInfoQueryDTO userInfoQueryDTO) {

        RowsDataVO<UserInfoQueryResultDTO> dataVO = new RowsDataVO();
        QueryConditions conditions = new QueryConditions();

        conditions.addCondition("yonghuming", EConditionOperator.LIKE, userInfoQueryDTO.getYonghuming());
        conditions.addCondition("yonghuleixing", EConditionOperator.LIKE, userInfoQueryDTO.getYonghuleixing());
        conditions.addCondition("suoshuxitong", EConditionOperator.LIKE, userInfoQueryDTO.getSuoshuxitong());
        conditions.addCondition("shanchubiaoshi", EConditionOperator.EQULS, XtYewuyonghu.SHANCHUBIAOSHI_WU_XIOA);
        conditions.addCondition("jiudianId", EConditionOperator.EQULS, userInfoQueryDTO.getJiudianId());

        MyExample example = new MyExample(XtYewuyonghu.class, conditions, userInfoQueryDTO.getOrderFields());
        Page<UserInfoQueryResultDTO> page = PageHelper.startPage(userInfoQueryDTO.getPageNo(), userInfoQueryDTO.getPageSize());
        List<XtYewuyonghu> xtYewuyonghus = xtYewuyonghuMapper.selectByExample(example);

        List<UserInfoQueryResultDTO> noticeQueryResultDTOList = xtYewuyonghus.stream().map(n -> {
            UserInfoQueryResultDTO dto = new UserInfoQueryResultDTO();
            BeanUtils.copyProperties(n, dto);
            dto.setYonghuleixingMingCheng(dictInfoCacheExtractor.getDictValue(SysDicConstant.YONGHULEIXING, String.valueOf(dto.getYonghuleixing())));
            dto.setSuoshuxitongMingCheng(dictInfoCacheExtractor.getDictValue(SysDicConstant.SUOSHUXITONG, dto.getSuoshuxitong()));
            dto.setJiudianMingCheng(hotelInfoCacheExtractor.getHotelNameById(dto.getJiudianId()));
            return dto;
        }).collect(Collectors.toList());

        dataVO.setPageNo(page.getPageNum());
        dataVO.setTotalRecords(page.getTotal());
        dataVO.setTotalPages(page.getPages());
        dataVO.setRows(noticeQueryResultDTOList);
        return dataVO;
    }

    public UserDetailQueryResultDTO detail(UserDetailQueryDTO userDetailQueryDTO) {
        XtYewuyonghu xtYewuyonghu = xtYewuyonghuMapper.selectByPrimaryKey(userDetailQueryDTO.getId());
        UserDetailQueryResultDTO resultDTO = new UserDetailQueryResultDTO();
        BeanUtils.copyProperties(xtYewuyonghu, resultDTO);
        resultDTO.setYonghuleixingMingCheng(dictInfoCacheExtractor.getDictValue(SysDicConstant.YONGHULEIXING, String.valueOf(resultDTO.getYonghuleixing())));
        resultDTO.setSuoshuxitongMingCheng(dictInfoCacheExtractor.getDictValue(SysDicConstant.SUOSHUXITONG, resultDTO.getSuoshuxitong()));
        resultDTO.setUserRolesQueryResultDtos(xtYonghujueseGuanxiMapper.selectRolesByUserId(userDetailQueryDTO.getId()));
        return resultDTO;
    }

    public List<UserRolesQueryResultDto> getUserRolesList(UserRolesQueryDto userInfoDetailDto) {
        return xtYonghujueseGuanxiMapper.selectRolesByUserId(userInfoDetailDto.getUserId());
    }

    /**
     * @param userInfoAddDTO
     * @return
     */
    public ResultVO addPmsUserInfo(UserInfoPMSAddDTO userInfoAddDTO) {
        UserInfoAddDTO infoAddDTO = new UserInfoAddDTO();
        BeanUtils.copyProperties(userInfoAddDTO, infoAddDTO);
        infoAddDTO.setJiudianId(manageUserCache.getJiudianId());
        infoAddDTO.setSuoshuxitong(XtYewuyonghu.SUOSHUXITONG_PMS);
        return addUserInfo(infoAddDTO);

    }

    /**
     * 修改当前登录用户密码
     *
     * @param userPasswordUpdateDTO
     * @return
     */
    public ResultVO updateUserPassword(UserPasswordUpdateDTO userPasswordUpdateDTO) {
        ResultVO resultVO = ResultVO.fail();

        LoginManageResultVO loginManageResultVO = manageUserCache.getLoginManageUserInfo();

        //验证旧密码
        String password = CustomSecurity.createUserPassword(loginManageResultVO.getYonghuming(), loginManageResultVO.getYan(), userPasswordUpdateDTO.getOldPwd());
        if (!password.equals(loginManageResultVO.getMima())) {
            resultVO.setMessage("旧密码错误，修改失败");
            return resultVO;
        }

        //修改新密码
        XtYewuyonghu yewuyonghu = new XtYewuyonghu();
        BeanUtils.copyProperties(loginManageResultVO, yewuyonghu);
        yewuyonghu.setYan(UUIDUtil.getUUID());
        String newPwd = CustomSecurity.createUserPassword(yewuyonghu.getYonghuming(), yewuyonghu.getYan(), userPasswordUpdateDTO.getNewPwd());
        yewuyonghu.setMima(newPwd);
        yewuyonghu.setGengxinshijian(new Date());
        xtYewuyonghuMapper.updateByPrimaryKeySelective(yewuyonghu);

        //退出当前登录
        loginService.userLoginOut();

        resultVO.setCode(ErrorEnum.ERROR_215.getCode());
        resultVO.setMessage("修改成功");
        return resultVO;
    }

}
